package cn.wjssl.domain.activity.service.armory;

import cn.wjssl.domain.activity.model.entity.ActivitySkuEntity;
import cn.wjssl.domain.activity.repository.IActivityRepository;
import cn.wjssl.types.common.Constants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * 活动装配实现类
 */
@Slf4j
@Service
public class ActivityArmory implements IActivityArmory, IActivityDispatch {

    @Resource
    private IActivityRepository repository;

    /**
     * 通过sku 查询 activity_sku表
     * @param sku
     * @return
     */
    @Override
    public boolean assembleActivitySku(Long sku) {
        /**
         * 通过sku，从sku表中获取SkuEntity实体，对应的activity_id, 库存信息stock_count, 活动次数activity_count_id
         *
         * 1. 将stock_count, 商品SKU的库存缓存到redis
         * 2. 根据activity_id将活动实体ActivityEntity装配缓存到redis
         * 3. 根据activity_count_id将活动次数实体ActivityCountEntity装配到redis
         */
        ActivitySkuEntity activitySkuEntity = repository.queryActivitySku(sku);
        cacheActivitySkuStockCount(sku, activitySkuEntity.getStockCount());
        repository.queryRaffleActivityByActivityId(activitySkuEntity.getActivityId());
        repository.queryRaffleActivityCountByActivityCountId(activitySkuEntity.getActivityCountId());
        return true;
    }

    /**
     * 通过activityId 查询 activity_sku表
     * @param activityId
     * @return
     */
    @Override
    public boolean assembleActivitySkuByActivityId(Long activityId) {
        /**
         * 通过activityId，从sku表中获取该活动id对应的所有skuList
         *
         * 1. 遍历skuList, 缓存sku和其对应的剩余库存, 查询该商品对应的 count表, 缓存用户在下单该商品后, 可以在活动上有多少次抽奖机会
         * 2. 通过活动Id, 查询activity表, 查询到对应的实体对象, 存有策略Id
         */
        List<ActivitySkuEntity> activitySkuEntityList = repository.queryActivitySkuListByActivityId(activityId);
        for (ActivitySkuEntity activitySkuEntity : activitySkuEntityList) {
            // 缓存库存
            cacheActivitySkuStockCount(activitySkuEntity.getSku(), activitySkuEntity.getStockCountSurplus());
            // 缓存抽奖次数
            repository.queryRaffleActivityCountByActivityCountId(activitySkuEntity.getActivityCountId());
        }
        // 缓存活动实体
        repository.queryRaffleActivityByActivityId(activityId);
        return true;
    }

    // 内部方法, 缓存活动初始SKU库存信息
    private void cacheActivitySkuStockCount(Long sku, Integer stockCount) {
        String cacheKey = Constants.RedisKey.ACTIVITY_SKU_STOCK_COUNT_KEY + sku;
        repository.cacheActivitySkuStockCount(cacheKey, stockCount);
    }

    /**
     * 扣减sku库存
     * @param sku 互动SKU
     * @param endDateTime 活动结束时间，根据结束时间设置加锁的key为结束时间
     * @return
     */
    @Override
    public boolean subtractionActivitySkuStock(Long sku, Date endDateTime) {
        String cacheKey = Constants.RedisKey.ACTIVITY_SKU_STOCK_COUNT_KEY + sku;
        return repository.subtractionActivitySkuStock(sku, cacheKey, endDateTime);
    }
}
